﻿using Org.BouncyCastle.Asn1.X509;
using SqlSugar;
using System.Collections.Generic;
using System.Diagnostics;
using Zhaoxi.SqlSugar.Common;
using Zhaoxi.SqlSugar.Models;

namespace Zhaoxi.SqlSugarAdvanced
{
    public class WriteOperationInfo
    {
        #region 新增--数据插入到数据库
        /// <summary>
        /// 新增--数据插入到数据库
        /// </summary>
        public static void AddData()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };

            Student student = new Student()
            {
                Name = "返回自增列",
                SchoolId = 1,
                CreateTime = DateTime.Now
            };

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                #region 创建表
                db.CodeFirst.InitTables(typeof(Snowflake)); //初始化表
                db.CodeFirst.InitTables(typeof(Student)); // 初始化表
                #endregion

                #region 单条插入
                {
                    int count = db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    //插入返回自增列 (实体除ORACLE外实体要配置自增，Oracle需要配置序列)
                    int idPk = db.Insertable(student) // 创建插入对象
                        .ExecuteReturnIdentity(); //返回自增列ID

                    //返回雪花ID 看文档3.0具体用法（在最底部）
                    Snowflake snowflakeModel = new Snowflake()
                    {
                        Name = "返回雪花ID",
                        SchoolId = 1
                    };
                    db.Deleteable<Snowflake>().ExecuteCommand(); // 删除所有数据
                    long id = db.Insertable(snowflakeModel) // 创建插入对象
                        .ExecuteReturnSnowflakeId(); // 返回雪花ID

                    //实用技巧2： 强制设置表名（默认表名来自实体） 
                    db.Insertable(student) // 创建插入对象
                        .AS("dbstudent") // 强制设置表名为dbstudent - 如果实体和数据库表名不一致可以使用这个方法
                        .ExecuteCommand(); // 执行插入命令

                    //字典插入
                    Dictionary<string, object> dc = new Dictionary<string, object>();
                    dc.Add("StudentName", "字典插入"); //不能写实体中的属性名，必须和数据库保持一致
                    dc.Add("SchoolId", 23);
                    dc.Add("CreateTime", DateTime.Now);
                    db.Insertable(dc) // 创建插入对象 - 支持字典插入
                        .AS("dbstudent") // 强制设置表名为dbstudent - 如果实体和数据库表名不一致可以使用这个方法
                        .ExecuteCommand(); // 执行插入命令

                    db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    //匿名对象 插入
                    var obj = new
                    {
                        StudentName = "匿名对象 插入",
                        CreateTime = DateTime.Now,
                        SchoolId = "456"
                    };
                    db.Insertable<Dictionary<string, object>>(obj) // 创建插入对象 - 支持匿名对象插入
                        .AS("[dbstudent]") // 强制设置表名为dbstudent - 如果实体和数据库表名不一致可以使用这个方法
                      .ExecuteCommand(); // 执行插入命令
                }
                #endregion

                #region 忽略-不插入指定字段
                {
                    db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    //忽略 name SchoolId
                    int id = db.Insertable(student) // 创建插入对象
                        .IgnoreColumns(it => new { it.Name }) // 忽略Name字段 - name字段不插入值
                        .ExecuteReturnIdentity(); // 返回自增列ID

                    db.Insertable(student) // 创建插入对象
                        .IgnoreColumns("Name", "SchoolId") // 忽略Name和SchoolId字段 - name和SchoolId字段不插入值
                        .ExecuteReturnIdentity(); // 返回自增列ID
                }
                #endregion

                #region 只插入指定字段
                {
                    db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    //忽略 name testid
                    int id = db.Insertable(student) // 创建插入对象
                        .InsertColumns(it => new { it.Name }) // 只插入Name字段 - name字段插入值
                        .ExecuteReturnIdentity(); // 返回自增列ID

                    db.Insertable(student) // 创建插入对象
                        .InsertColumns("Name", "SchoolId") // 只插入Name和SchoolId字段 - name和SchoolId字段���入值
                        .ExecuteReturnIdentity(); // 返回自增列ID
                }
                #endregion

                #region 批量插入
                {

                    db.Deleteable<Student>().ExecuteCommand(); // 删除所有数据
                    List<Student> addlist = new List<Student>();
                    for (int i = 0; i < 100; i++)
                    {
                        addlist.Add(new Student()
                        { 
                            Name = $"Name_{i}",
                            SchoolId = i,
                            CreateTime = DateTime.Now
                        });
                    }
                    //(1)、非参数化插入（防注入） 
                    //优点：综合性能比较平均，列少1万条也不慢，属于万写法,不加事务情况下部分库有失败回滚机质
                    //缺点：数据量超过5万以上占用内存会比较大些，内存小可以用下面2种方式处理
                    db.Insertable(addlist) // 创建插入对象 - 常用的插入方法
                        .ExecuteCommand(); // 执行插入命令


                    //(2)、使用参数化内部分页插入
                    //优点：500条以下速度最快，兼容所有类型和emoji，10万以上的大数据也能跑，就是慢些，内部分批量处理过了。
                    //缺点：500以上就开始慢了，要加事务才能回滚 
                    db.Insertable(addlist) // 创建插入对象
                        .UseParameter() // 使用参数化插入 - 防止SQL注入
                        .ExecuteCommand();//5.0.3.8-Preview及以上版本支持（NUGET搜索勾上包括预览）


                    //(3)、大数据写入（特色功能：大数据处理上比所有框架都要快30%）
                    //优点：1000条以上性能无敌手
                    //缺点：不支持数据库默认值， API功能简单， 小数据量并发执行不如普通插入，插入数据越大越适合用这个
                    //新功能 5.0.44
                    db.Fastest<Student>() // 创建快速插入对象 - 适合大数据量插入
                        .PageSize(100000) // 设置每次批量插入的条数 - 默认10000条
                        .BulkCopy(addlist); // 执行批量插入命令 - 适合大数据量插入
                }
                #endregion

                #region 分页插入
                {
                    db.Deleteable<Student>() // 删除所有数据
                        .ExecuteCommand(); 
                    List<Student> addlist = new List<Student>();
                    for (int i = 0; i < 100; i++)
                    {
                        addlist.Add(new Student()
                        {
                            Name = $"Name_{i}",
                            SchoolId = i,
                            CreateTime = DateTime.Now
                        });
                    }

                    //分页插入 ，如果不支持db.Fastest分页插入也是可以提升一下性能的
                    db.Utilities.PageEach(addlist, 10, pageList => // 每10条数据分页处理一次
                    {
                        db.Insertable(pageList) // 创建插入对象
                        .ExecuteCommand(); // 执行插入命令
                        //db.Insertable(List<实体>).UseParameter().ExecuteCommand() 可以试试和上面哪个性能高用哪个
                    });
                }
                #endregion

                #region 大数据插入
                {
                    List<Student> students = new List<Student>();
                    db.Deleteable<Student>().ExecuteCommand();
                    for (int i = 0; i < 1000000; i++)
                    {
                        students.Add(new Student()
                        {
                            Name = $"Name_{i}",
                            SchoolId = i,
                            CreateTime = DateTime.Now
                        });
                    }

                    //Stopwatch stopwatch = Stopwatch.StartNew();
                    //stopwatch.Start();
                    ////插入 100万 数秒时间
                    //db.Insertable<Student>(students).ExecuteCommand();//性能 比现有任何Bulkcopy都要快30%
                    //stopwatch.Stop();
                    //Console.WriteLine($"普通方式：1000000条数据大概用时：{stopwatch.ElapsedMilliseconds} 毫秒");

                    db.Deleteable<Student>().ExecuteCommand();
                    Stopwatch stopwatch1 = Stopwatch.StartNew();
                    stopwatch1.Start();
                    //插入 100万 数秒时间
                    db.Fastest<Student>() // 创建快速插入对象 - 适合大数据量插入
                        .BulkCopy(students);//性能 比现有任何Bulkcopy都要快30%
                    stopwatch1.Stop();
                    Console.WriteLine($"BulkCopy大数据操作：1000000条数据大概用时：{stopwatch1.ElapsedMilliseconds} 毫秒");
                }
                #endregion

                #region Guid主键自动赋值 
                {
                    //只要设置为主键，并且C#类型是Guid 只要不传值，会自动赋值 
                    // 注意只能用： ExecuteCommand 方法不能用自增列的方法

                    db.CodeFirst.InitTables(typeof(UserInfo)); // 初始化表
                    db.Deleteable<UserInfo>().ExecuteCommand();
                    UserInfo user = new UserInfo()
                    {
                        Name = "Richard老师",
                        CreateTime = DateTime.Now,
                    };
                    db.Insertable(user) // 创建插入对象
                        .ExecuteCommand();

                }
                #endregion

                #region 调用实体内方法
                {
                    db.CodeFirst.InitTables(typeof(UnitInsertMethod)); // 初始化表
                    db.Deleteable<UnitInsertMethod>().ExecuteCommand();
                    db.Insertable(new UnitInsertMethod() { Name = "1" }) // 创建插入对象
                        .CallEntityMethod(it => it.Create()) // 调用实体方法 - 这里是调用UnitInsertMethod类的Create方法
                        .ExecuteCommand(); // 执行插入命令

                    db.Updateable(new UnitInsertMethod() { Name = "1" }) // 创建更新对象
                        .CallEntityMethod(it => it.modify("admint")) // 调用实体方法 - 这里是调用UnitInsertMethod类的modify方法
                        .ExecuteCommand(); // 执行更新命令
                }
                #endregion

                #region Select Into 临时表 - 没什么作用
                {
                    db.Ado.OpenAlways();//长连接
                    db.Queryable<UserInfo>() // 查询UserInfo表
                        .Select(" * into #temp") // 使用Select Into语句创建临时表 #temp
                        .ToList();//插入临时表
                    var tempList = db.Queryable<dynamic>() // 查询临时表
                        .AS("#temp") // 指定临时表名
                        .ToList();//查询临时表
                }
                #endregion
            }
        }
        #endregion

        #region 修改--数据更新到数据库
        /// <summary>
        /// 修改数据
        /// </summary>
        public static void UpdateData()
        {
            //如何输出Sql语句 
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001,
                IsAutoCloseConnection = true,
                DbType = DbType.SqlServer
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {

                //初始化一条数据测试使用
                db.Insertable<Student>(new Student()
                {
                    CreateTime = DateTime.Now,
                    Name = "测试数据",
                    SchoolId = 1,
                }).ExecuteCommand();

                {  //输出Sql语句 - Sql语句执行委托 - 只要有sql语句执行，就会触发这个委托 - 可以用于记录sql语句
                    db.Aop.OnLogExecuting = (s, p) =>
                    {
                        Console.WriteLine("----------------------------");
                        Console.WriteLine($"Sql语句:{s}");
                    };
                }

                Student student = db.Queryable<Student>() // 查询一条数据
                    .First(); // 获取第一条数据 - 这里假设已经有数据了
                //单条更新 - 更新整条数据-如果精度不高的话可以使用
                {
                    student.CreateTime = DateTime.Now;
                    db.Updateable<Student>(student) // 创建更新对象
                        .ExecuteCommand(); //右标题1 下面的所有菜单
                }

                //按需更新
                {
                    db.Tracking(student);// 创建跟踪 - 跟踪对象会被自动更新 - 按需更新
                    student.Name = "a1" + Guid.NewGuid(); // 修改Name字段
                    //只改修改了name那么只会更新name
                    //跟踪批量操作不会生效，原因：默认最佳性能（跟踪批量性能差，自已循环）
                    //可以清空跟踪db.TempItems = null;
                    db.Updateable(student) // 创建更新对象
                        .ExecuteCommand();
                }

                //批量修改
                {
                    List<Student> list = db.Queryable<Student>() // 查询多条数据
                        .Take(20) // 取前20条数据
                        .ToList(); // 转换为List<Student>类型
                    foreach (var item in list)
                    {
                        item.Name = "New Name" + DateTime.Now;
                    }
                    db.Updateable(list) // 创建批量更新对象
                        .ExecuteCommand(); // 执行批量更新命令

                    //批量更新中，按需是不能操作的 - 批量按需更新不生效
                    foreach (var item in list)
                    {
                        item.Name = "New Name 02" + DateTime.Now;
                    }
                    db.Tracking(list);//创建跟踪
                    db.Updateable(list) // 创建批量更新对象
                        .ExecuteCommand(); // 执行批量更新命令
                }

                //大数据量操作
                {
                    db.Deleteable<Student>().ExecuteCommand();//删除所有数据
                    List<Student> addlist = new List<Student>();
                    for (int i = 0; i < 1000000; i++)
                    {
                        addlist.Add(new Student()
                        {
                            CreateTime = DateTime.Now,
                            Name = "Richard" + i,
                            SchoolId = i
                        });
                    }
                    ////初始化1000000条数据到数据库
                    db.Fastest<Student>() // 创建快速插入对象 - 适合大数据量插入
                        .BulkCopy(addlist); // 执行批量插入命令 - 适合大数据量插入


                    //大数据批量更新  适合列多数据多的更新 (MySql连接字符串要加AllowLoadLocalInfile=true )
                    //普通方式操作
                    {

                        foreach (var item in addlist)
                        {
                            item.Name = $"批量修改第一次-Updateable方式";
                        }

                        Console.WriteLine("普通方式批量修改1000000条数据开始计时~~");

                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        db.Updateable<Student>(addlist) // 创建批量更新对象
                            .ExecuteCommand(); // 执行批量更新命令
                        stopwatch.Stop();
                        Console.WriteLine($"批量修改1000000条数据共：{stopwatch.ElapsedMilliseconds} ms");
                    }

                    //大数据量BulkUpdate操作--高性能
                    {
                        foreach (var item in addlist)
                        {
                            item.Name = $"批量修改第二次=BulkUpdate方式";
                        }
                        Console.WriteLine("大数据量操作-BulkUpdate方式批量修改1000000条数据开始计时~~");

                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        db.Fastest<Student>() // 创建快速插入对象 - 适合大数据量插入
                            .BulkUpdate(addlist); // 执行批量更新命令 - 适合大数据量更新
                        stopwatch.Stop();
                        Console.WriteLine($"批量修改1000000条数据共：{stopwatch.ElapsedMilliseconds} ms");
                    }
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //忽略某一列不更新 
                {
                    Student studentUp = db.Queryable<Student>() // 查询一条数据
                        .First(); // 获取第一条数据 - 这里假设已经有数据了
                    studentUp.SchoolId = 234;
                    studentUp.Name = "忽略某一列不更新";
                    studentUp.CreateTime = DateTime.Now.AddYears(5);
                    var result = db.Updateable(studentUp) // 创建更新对象
                       .IgnoreColumns(it => new
                       {
                           it.CreateTime
                       }) // 忽略CreateTime字段 - CreateTime字段不更新
                       .ExecuteCommand(); // 执行更新命令
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //只更新某列--按需更新
                {
                    Student studentUp = db.Queryable<Student>().First(); // 查询一条数据
                    studentUp.SchoolId = 345;
                    studentUp.Name = "只更新某列";
                    studentUp.CreateTime = DateTime.Now.AddYears(6);
                    var result = db.Updateable(studentUp) // 创建更新对象
                        .UpdateColumns(it => new { it.Name, it.CreateTime }) // 只更新Name和CreateTime字段 - 只更新Name和CreateTime字段
                        .ExecuteCommand(); // 执行更新命令
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //NULL列不更新 
                {
                    Student studentUp = db.Queryable<Student>().First(); // 查询一条数据
                    studentUp.SchoolId = 456;
                    studentUp.Name = null;

                    //更新忽略null字段

                    var result = db.Updateable(studentUp) // 创建更新对象
                        .IgnoreColumns(ignoreAllNullColumns: true) // 忽略所有null列 - null列不更新
                        .ExecuteCommand(); // 执行更新命令

                    //更新忽略null并且忽略默认值 (比如int默认值是0就不更新)

                    var result1 = db.Updateable(studentUp) // 创建更新对象
                        .IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true) // 忽略所有null列和默认值 - null列不更新，默认值不更新
                        .ExecuteCommand(); // 执行更新命令
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //无主键/指定列
                {
                    //WhereColumns(it=>new { it.Id,it.Name}) //条件列不会被更新，只会作为条件 
                    Student studentUp = db.Queryable<Student>().First();
                    studentUp.SchoolId = 567;
                    studentUp.Name = null;

                    var result = db.Updateable(studentUp) // 创建更新对象
                        .WhereColumns(it => new
                        {
                            it.Id
                        }) // 指定更新条件列 - 只更新Id列作为条件
                        .ExecuteCommand();//更新单 条根据ID


                    var result1 = db.Updateable(studentUp) // 创建更新对象
                        .WhereColumns(it => new
                        {
                            it.Id
                        }) // 指定更新条件列 - 只更新Id列作为条件
                        .ExecuteCommand();//更新集合根据ID by id
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //条件更新
                {
                    //如果是集合操作请更新到5.0.4版本之前版本禁止使用, 并且只有部分库支持
                    Student studentUp = db.Queryable<Student>().First();
                    studentUp.Name = "条件更新";

                    var result = db.Updateable(studentUp) // 创建更新对象
                        .Where(it => it.Id == 7003783) //   指定更新条件 - 只更新Id等于7003783的记录
                        .ExecuteCommand(); // 执行更新命令 - 只更新Id等于7003783的记录
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //重新赋值更新
                {
                    Student studentUp = db.Queryable<Student>().First(); // 查询一条数据
                    studentUp.SchoolId = 678;
                    studentUp.Name = "重新赋值";

                    // studentUp.Name值的基础上在处理
                    var result = db.Updateable(studentUp) // 创建更新对象
                            .ReSetValue(it =>
                            {
                                it.Name = it.Name + "a";
                            }) // 重新赋值Name字段 - Name字段值在原有基础上加上"a"
                           .ExecuteCommand(); // 执行更新命令 - 只更新Name字段

                    //多个字段          
                    var result1 = db.Updateable(studentUp) // 创建更新对象
                               .ReSetValue(it =>
                               {
                                   it.Name = it.Name + "a";
                                   it.CreateTime = DateTime.Now;
                               }) // 重新赋值Name和CreateTime字段 - Name字段值在原有基础上加上"a"，CreateTime字段值为当前时间
                              .ExecuteCommand(); // 执行更新命令 - 只更新Name和CreateTime字段
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //表达式更新
                {
                    var result = db.Updateable<Student>() // 创建更新对象
                        .SetColumns(it => new Student()
                        {
                            Name = "a",
                            CreateTime = DateTime.Now
                        }) // 使用表达式更新 - 更新Name和CreateTime字段
                        .Where(c => c.Id == 7003783) // 指定更新条件 - 只更新Id等于7003783的记录
                        .ExecuteCommand();//正确没参数我们称为表达式更新  
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //批量更新 In
                {
                    var ids = db.Queryable<Student>() // 查询多条数据
                        .Select(c => c.Id) // 只选择Id字段
                        .Take(5) // 取前5条数据
                        .ToList(); // 转换为List<int>类型

                    var result = db.Updateable<Student>() // 创建批量更新对象
                                 .SetColumns(it => it.Name == "a")// 设置Name字段为"a"
                                .Where(it => ids.Contains(it.Id)) // 指定更新条件 - 只更新Id在ids列表中的记录
                                .ExecuteCommand(); //   执行批量更新命令 - 只更新Id在ids列表中的记录

                    // in (1,2,3)
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //表达式无实体更新
                {   // 无实体更新 - 只更新指定字段 - 可以实现更新所有字段
                    var result = db.Updateable<DbTableInfo>() // 创建无实体更新对象
                       .AS("dbstudent") // 强制设置表名为dbstudent
                       .SetColumns("StudentName", "表达式无实体更新") // 设置StudentName字段为"表达式无实体更新"
                       .Where("id=7003782") // 指定更新条件 - 只更新Id等于7003782的记录
                       .ExecuteCommand(); // 执行无实体更新命令 - 只更新Id等于7003782的记录
                }
            }

            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                //根据字典更新
                {
                    //字典
                    Dictionary<string, object> dt = new Dictionary<string, object>();
                    dt.Add("id", 7003782);
                    dt.Add("StudentName", "字典更新");
                    dt.Add("createTime", DateTime.Now);
                    var tResult = db.Updateable(dt) // 创建字典更新对象
                        .AS("dbstudent") // 强制设置表名为dbstudent
                        .WhereColumns("id") // 指定更新条件列 - 只更新Id列作为条件
                        .ExecuteCommand(); // 执行字典更新命令 - 只更新Id列作为条件

                    //字典集合
                    var dtList = new List<Dictionary<string, object>>();
                    dtList.Add(dt);

                    var t666 = db.Updateable(dtList) // 创建字典集合更新对象
                        .AS("dbstudent") // 强制设置表名为dbstudent
                        .WhereColumns("id") // 指定更新条件列 - 只更新Id列作为条件
                        .ExecuteCommand(); // 执行字典集合更新命令 - 只更新Id列作为��件
                }
            }
        }
        #endregion

        #region 删除数据
        /// <summary>
        /// 删除数据
        /// </summary>
        public static void DeleteData()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) // 创建SqlSugarClient实例
            {
                db.CodeFirst.InitTables(typeof(StudentInfo)); // 初始化StudentInfo表
                //表中数据全部清空，清除，自增初始化
                db.DbMaintenance.TruncateTable<StudentInfo>(); // 清空StudentInfo表数据并重置自增列
                //输出Sql语句
                db.Aop.OnLogExecuting = (s, p) =>
                {
                    Console.WriteLine("----------------------------");
                    Console.WriteLine($"Sql语句:{s}");
                };

                List<StudentInfo> addlist = new List<StudentInfo>();
                for (int i = 0; i < 500; i++)
                {
                    addlist.Add(new StudentInfo()
                    {
                        Id = i + 1,
                        CreateTime = DateTime.Now,
                        Isdeleted = false,
                        Name = $"名称_{i + 1}",
                        SchoolId = i + 1,
                    });
                }
                db.Deleteable<StudentInfo>() // 删除所有数据
                    .ExecuteCommand(); // 清空StudentInfo表数据
                db.Insertable<StudentInfo>(addlist) // 批量插入数据
                    .ExecuteCommand(); // 执行批量插入命令

                //单个实体删除
                {
                    db.Deleteable<StudentInfo>() // 创建删除对象
                        .Where(new StudentInfo() { Id = 1 }) // 指定删除条件 - 删除Id等于1的记录
                        .ExecuteCommand(); // 执行删除命令 - 删除Id等于1的记录
                }

                //List<实体> 删除集合
                List<StudentInfo> list = new List<StudentInfo>()
                {
                  new StudentInfo() { Id = 2 },
                  new StudentInfo() { Id = 3 }
                };
                db.Deleteable<StudentInfo>(list) // 创建删除对象
                    .ExecuteCommandHasChange(); // 执行删除命令 - 删除Id等于2和3的记录

                //根据主键删除
                db.Deleteable<StudentInfo>() // 创建删除对象
                    .In(4) // 指定主键删除 - 删除Id等于4的记录
                    .ExecuteCommand(); // 执行删除命令 - 删除Id等于4的记录

                //无主键删除
                db.Deleteable<StudentInfo>() // 创建删除对象
                    .In(it => it.Id, 5) // 指定无主键删除 - 删除Id等于5的记录
                    .ExecuteCommand(); // 执行删除命令 - 删除Id等于5的记录

                //根据主键数组删除
                db.Deleteable<StudentInfo>() // 创建删除对象
                    .In(new int[] { 6, 7 }) // 指定主键数组删除 - 删除Id等于6和7的记录
                    .ExecuteCommand(); // 执行删除命令 - 删除Id等于6和7的记录

                //无主键数组删除
                db.Deleteable<StudentInfo>() // 创建删除对象
                    .In(it => it.Id, new int[] { 8, 9 }) // 指定无主键数组删除 - 删除Id等于8和9的记录
                    .ExecuteCommand(); // 执行删除命令 - 删除Id等于8和9的记录

                //表达式删除
                db.Deleteable<StudentInfo>() // 创建删除对象
                    .Where(it => it.Id == 10) // 指定删除条件 - 删除Id等于10的记录
                    .ExecuteCommand(); // 执行删除命令 - 删除Id等于10的记录

                //无实体删除
                db.Deleteable<object>() // 创建无实体删除对象
                    .AS("[StudentInfo]") // 强制设置表名为StudentInfo - 如果实体和数据库表名不一致可以使用这个方法
                    .Where("id=@id", new { id = 11 }) // 指定删除条件 - 删除Id等于11的记录
                    .ExecuteCommand(); // 执行无实体删除命令 - 删除Id等于11的记录

                db.Deleteable<object>() // 创建无实体删除对象
                    .AS("[StudentInfo]") // 强制设置表名为StudentInfo - 如果实体和数据库表名不一致可以使用这个方法
                    .Where("id in (@id) ", new { id = new int[] { 12, 13, 14 } }) // 指定删除条件 - 删除Id等于12、13和14的记录
                    .ExecuteCommand();//批量


                //根据字典集合删除 

                Dictionary<string, object> parameter = new Dictionary<string, object>();
                parameter.Add("Id", 15);
                List<Dictionary<string, object>> dic = new List<Dictionary<string, object>>()
                {
                    parameter
                };

                db.Deleteable<object>() // 创建字典集合删除对象
                    .AS("[StudentInfo]") // 强制设置表名为StudentInfo - 如果实体和数据库表名不一致可以使用这个方法
                    .WhereColumns(dic) // 指定删除条件列 - 删除Id等于15的记录
                    .ExecuteCommand(); // 执行字典集合删除命令 - 删除Id等于15的记录
            }
        }
        #endregion

        #region 存在更新，不存在插入
        /// <summary>
        /// 存在更新，不存在插入
        /// </summary>
        public static void AddOrUpdate()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) // 创建SqlSugarClient实例`
            {
                db.Deleteable<StudentInfo>() // 删除所有数据
                    .ExecuteCommand(); // 清空StudentInfo表数据


                //不存在就插入，存在就修改
                {
                    StudentInfo studentInfo = new StudentInfo()
                    {
                        Id = 31,
                        Name = "新增的数据",
                        CreateTime = DateTime.Now,
                        Isdeleted = false,
                        SchoolId = 0,
                    };
                    //新功能 5.0.6.2+ 
                    //存在更新 不存在插入 (默认是主键)
                    db.Storageable(studentInfo) // 创建存储对象
                        .ExecuteCommand();// 执行存储命令 - 存在更新，不存在插入
                    studentInfo.Name = "数据已存在就修改";
                    db.Storageable(studentInfo) // 创建存储对象
                        .ExecuteCommand();// 执行存储命令 - 存在更新，不存在插入

                    //批量操作---存在更新 不存在插入 
                    List<StudentInfo> addlist = new List<StudentInfo>();
                    for (int i = 0; i < 20; i++)
                    {
                        addlist.Add(new StudentInfo()
                        {
                            Id = i + 1,
                            CreateTime = DateTime.Now,
                            Isdeleted = false,
                            Name = $"名称_{i + 1}",
                            SchoolId = i + 1,
                        });
                    }
                    db.Storageable<StudentInfo>(addlist) // 创建存储对象
                        .ExecuteCommand(); // 执行存储命令 - 存在更新，不存在插入
                    foreach (var item in addlist)
                    {
                        item.Name = $"批量修改";
                    }
                    db.Storageable<StudentInfo>(addlist) // 创建存储对象
                        .ExecuteCommand(); // 执行存储命令 - 存在更新，不存在插入
                }

                StudentInfo obj = new StudentInfo()
                {
                    CreateTime = DateTime.Now,
                    Isdeleted = false,
                    Name = $"名称_41",
                    SchoolId = 41,
                };

                //等于0插入否则更新（不验证数据库是否存在）
                {
                    db.Storageable(obj) // 创建存储对象
                   .SplitUpdate(it => it.Item.Id > 0) // 分割更新 - 如果Id大于0则更新
                   .SplitInsert(it => true) // 分割插入 - 如果满足条件则插入 如果Id等于0则插入
                   .ExecuteCommand(); // 执行存储命令 - 分割更新和分割插入

                    obj.Id = 1;
                    obj.Name = "修改一下数据";
                    db.Storageable(obj) // 创建存储对象
                      .SplitUpdate(it => it.Item.Id > 0) // 分割更新 - 如果Id大于0则更新
                      .SplitInsert(it => true) // 分割插入 - 如果满足条件则插入 如果Id等于0则插入
                      .ExecuteCommand(); // 执行存储命令 - 分割更新和分割插入
                }


                StudentInfo upobj = new StudentInfo()
                {
                    Id = 51,
                    CreateTime = DateTime.Now,
                    Isdeleted = false,
                    Name = $"名称_41",
                    SchoolId = 41,
                };
                upobj.Name = "测试数据";
                //忽略部分字段更新
                {
                    StorageableResult<StudentInfo> storageableResult = db.Storageable(upobj) // 创建存储对象
                        .ToStorage(); // 转换为存储对象
                    //不存在插入
                    storageableResult.AsInsertable // 转换为插入对象
                        .ExecuteCommand(); // 执行插入命令 - 如果不存在则插入 

                    //修改部分数据
                    upobj.Name = "Name修改了";
                    upobj.CreateTime = DateTime.Now.AddYears(10);

                    //存在更新
                    StorageableResult<StudentInfo> storageableResult1 = db.Storageable(upobj) // 创建存储对象
                       .ToStorage(); // 转换为存储对象
                    storageableResult1.AsUpdateable // 转换为更新对象
                        .IgnoreColumns(z => z.Name) // 忽略Name字段 - 不更新Name字段
                        .ExecuteCommand(); // 执行更新命令 - 如果存在则更新

                    var insertlist = storageableResult1.InsertList;
                    var updateList = storageableResult1.UpdateList;
                }

                //无主键操作
                {
                    upobj.CreateTime = DateTime.Now.AddYears(-5);
                    upobj.Name = "无主键操作";
                    db.Storageable(upobj) // 创建存储对象
                      .WhereColumns(it => it.Id)// 指定更新条件列 - 只更新Id列作为条件,当然支持多个 new {it.id,it.name}
                      .ExecuteCommand();// 执行存储命令 - 存在更新，不存在插入
                }

                //对于性能要求高，数据量大的可以这么操作，适合1万以上数据处理
                {
                    db.Deleteable<StudentInfo>() // 删除所有数据
                        .ExecuteCommand(); // 清空StudentInfo表数据

                    var addlist = new List<StudentInfo>();
                    for (int i = 0; i < 100000; i++)
                    {
                        addlist.Add(new StudentInfo()
                        {
                            Id = i + 1,
                            CreateTime = DateTime.Now,
                            Isdeleted = false,
                            Name = $"名称_{i + 1}",
                            SchoolId = i + 1,
                        });
                    }
                    StorageableResult<StudentInfo> storageableResult = db.
                        Storageable<StudentInfo>(addlist) // 创建存储对象
                        .ToStorage(); // 转换为存储对象
                    storageableResult.BulkCopy(); // 执行批量插入命令 - 如果不存在则插入




                }

                //字典用法
                {

                    db.Deleteable<StudentInfo>() // 删除所有数据
                        .ExecuteCommand(); // 清空StudentInfo表数据
                    List<Dictionary<string, object>> dictionaryList = new List<Dictionary<string, object>>();

                    Dictionary<string, object> dic = new Dictionary<string, object>();
                    dic.Add("Id", 456789);
                    dic.Add("SchoolId", 456789);
                    dic.Add("Name", "字典用法");
                    dic.Add("CreateTime", DateTime.Now);
                    dic.Add("Isdeleted", 1);
                    dictionaryList.Add(dic);

                    DataTableResult tableResult = db.Storageable(dictionaryList, "StudentInfo") // 创建存储对象
                        .WhereColumns("id") // 指定更新条件列 - Id列作为更新条件
                        .ToStorage();// 转换为存储对象

                    tableResult.AsInsertable // 转换为插入对象
                        .ExecuteCommand();// 执行插入命令 - 如果不存在则插入 如果是自增要添加IgnoreColumns

                    dictionaryList[0]["Name"] = "修改名称了";


                    DataTableResult tableResult1 = db.Storageable(dictionaryList, "StudentInfo") // 创建存储对象
                     .WhereColumns("id") // 指定更新条件列 - Id列作为更新条件
                     .ToStorage();// 转换为存储对象
                    tableResult1.AsUpdateable // 转换为更新对象
                        .ExecuteCommand(); // 执行更新命令 - 如果存在则更新
                }

                //分页处理更新
                {
                    List<StudentInfo> list = db.Queryable<StudentInfo>() // 查询多条数据
                        .ToList(); // 转换为List<StudentInfo>类型
                    //分页处理
                    db.Utilities.PageEach(list, 2000, pageList => // 每2000条数据分页处理一次
                    { 
                        db.Storageable(pageList) // 创建存储对象
                        .ExecuteCommand(); // 执行存储命令 - 存在更新，不存在插入
                        //条件列禁止varchar(50)以上，并且是主键或者有索引为佳 
                        //也可以用BulkCopy
                        //var x= db.Storageable<Order>(data).ToStorage();
                        //x.BulkCopy();
                        //x.BulkUpdate();  

                    });
                }

            }
        }
        #endregion
    }
}
